/* eslint-disable no-unused-vars */
/* eslint-disable brace-style */
/* eslint-disable no-undef */
/**
 *
 *
 *
 * axios封装
 * 请求拦截、响应拦截、错误统一处理
 *
 */
import axios from 'axios'
 import {
   getToken,
   removeToken
 } from '@/utils/auth'
import nprogress from 'nprogress'
import "nprogress/nprogress.css"//引入进度条样式
import {
  Message,
  Loading,
  Notification
} from 'element-ui'
import qs from 'qs'
import _ from 'lodash'
import store from '@/store/index.js'

// 设置公共请求头部
axios.defaults.baseURL = process.env.VUE_APP_BASE_API
axios.defaults.timeout = 20000

// loading对象
let loading

// 当前正在请求的数量
let needLoadingRequestCount = 0

// 显示loading
function showLoading(target) {
  // 后面这个判断很重要，因为关闭时加了抖动，此时loading对象可能还存在，
  // 但needLoadingRequestCount已经变成0.避免这种情况下会重新创建个loading
  if (needLoadingRequestCount === 0 && !loading) {
    loading = Loading.service({
      lock: true,
      text: 'Loading...',
      background: 'rgba(255, 255, 255, 0.5)',
      target: target || 'body'
    })
  }
  needLoadingRequestCount++
}

// 隐藏loading
function hideLoading() {
  needLoadingRequestCount--
  needLoadingRequestCount = Math.max(needLoadingRequestCount, 0) // 做个保护
  if (needLoadingRequestCount === 0) {
    // 关闭loading
    toHideLoading()
  }
}

// 防抖：将 300ms 间隔内的关闭 loading 便合并为一次。防止连续请求时， loading闪烁的问题。
var toHideLoading = _.debounce(() => {
  if(loading){
    loading.close()
    loading = null
  }
  
}, 300)

// 添加请求拦截器
axios.interceptors.request.use(config => {
  nprogress.start()
  // 登录后的token定义至headers
  if (getToken()) {
    config.headers.token = getToken()
  }
  if (store.state.detail.uuid_token) {//游客token
    config.headers.userTempId = store.state.detail.uuid_token
  }
  // 判断当前请求是否设置了不显示Loading
  if (config.headers.showLoading !== false) {
    showLoading(config.headers.loadingTarget)
  }
  return config
}, err => {
  // 判断当前请求是否设置了不显示Loading
  if (config.headers.showLoading !== false) {
    hideLoading()
  }
  Message.error('请求超时!')
  return Promise.resolve(err)
})

// 响应拦截器
axios.interceptors.response.use(
  response => {
    // 判断当前请求是否设置了不显示Loading（不显示自然无需隐藏）
    if (response.config.headers.showLoading !== false) {
      hideLoading()
    }
    nprogress.done()
    // 请求成功
    if (response.data.code === 200) {
      // Notification.success({
      //   title: '操作成功',
      //   message: response.data.msg,
      //   duration: 1000
      // })
      return response.data
    }
    else if (response.data.code === 205){
      return response.data
    }
    // 请求异常
    else if (response.code !== 200) {
      Notification.error({
        title: '错误',
        message: response.data.message,
        duration: 1200
      })
      return response.data
    }
  },
  error => {
    // 判断当前请求是否设置了不显示Loading（不显示自然无需隐藏）
    if (error.config.headers.showLoading !== false) {
      hideLoading()
    }
    if (error.response && error.response.data && error.response.data.message) {
      var jsonObj = JSON.parse(error.response.data.message)
      Message.error(jsonObj.message)
    } else {
      Message.error(error.message)// 错误提示
    }
    return Promise.reject(error)
  }
)

/**
    *
    * 请求使用方法
    *
 
    main.js 引入
 
    import http from './utils/http.js';
    Vue.prototype.axios = http;
 
    *
    * 常情况下
    * 每次发起请求页面上都会显示一个全屏的 loading 效果。
       this.axios.get("/api/menu")
           .then(response => {
               if(res.code == 0){
                   this.$message.success('OK!');
               }
       })
 
    * 如果在请求 header 中传递个 showLoading:false 参数，
    * 则该请求不会有 loading 效果。
 
        this.axios.get("/api/getDeviceDatas",{headers: {'showLoading': false}})
           .then(res => {
               if(res.code == 0){
                   this.$message.success('OK!');
               }
       })
 
    * 如果将请求 header 中 loadingTarget 设置为页面上某个元素的选择符
    * loading 效果会只显示在个元素区域上。
    * 比如我们下面代码我们只让 loading 遮罩显示在弹出框的内容区域上。
 
       this.axios.get("/api/controlApp?method=" + method, {headers: {'loadingTarget': '#anyValue'}})
           .then(res => {
               if(res.code == 0){
                   this.$message.success('OK!');
               }
        })
    * * */

/*
  * 封装get方法
   * @param url  地址
   * @param params  参数
   * @param loading  不传 -> 默认全屏loading效果, false -> 取消loading效果, '#id' or '.class' -> 指定区域loading效果
   * @returns {Promise}
   */
export function get(url, params = {}, loading, showLoading, loadingTarget) {
  if (typeof (loading) === 'boolean' && loading !== false) {
    showLoading = loading
    loadingTarget = 'body'
  } else if (typeof (loading) === 'string') {
    showLoading = true
    loadingTarget = loading
  } else if (loading === false) {
    showLoading = false
    loadingTarget = 'body'
  } else {
    showLoading = true
    loadingTarget = 'body'
  }
  return new Promise((resolve, reject) => {
    axios
      .get(url, {
        params: params,
        headers: { 'showLoading': showLoading, 'loadingTarget': loadingTarget }
      })
      .then(response => {
        resolve(response)
      })
      .catch(err => {
        reject(err)
      })
  })
}
/*
   * 封装post请求
   * @param url
   * @param data
   * @param loading
   * @returns {Promise}
   */
// json格式
export function post(url, data, loading, showLoading, loadingTarget) {
  if (typeof (loading) === 'boolean') {
    showLoading = loading
    loadingTarget = 'body'
  } else if (typeof (loading) === 'string') {
    showLoading = true
    loadingTarget = loading
  } else if (loading === false) {
    showLoading = false
    loadingTarget = 'body'
  } else {
    showLoading = true
    loadingTarget = 'body'
  }
  return new Promise((resolve, reject) => {
    axios.post(url, qs.stringify(data), { headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'showLoading': showLoading, 'loadingTarget': loadingTarget } }).then(
      response => {
        resolve(response)
      },
      err => {
        reject(err)
      }
    )
  })
}
// formData格式
export function From(url, data, loading, showLoading, loadingTarget) {
  if (typeof (loading) === 'boolean') {
    showLoading = loading
    loadingTarget = 'body'
  } else if (typeof (loading) === 'string') {
    showLoading = true
    loadingTarget = loading
  } else {
    showLoading = true
    loadingTarget = 'body'
  }//ruhe
  return new Promise((resolve, reject) => {
    axios
      .post(url, qs.stringify(data), {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
      })
      .then(
        response => {
          resolve(response.data)
        },
        err => {
          reject(err)
        }
      )
  })
}

/*
       JSON格式
   * 封装post请求
   * @param url
   * @param data
   * @param loading
   * @returns {Promise}
   */
// json格式
export function postJson(url, data, loading, showLoading, loadingTarget) {
  if (typeof (loading) === 'boolean') {
    showLoading = loading
    loadingTarget = 'body'
  } else if (typeof (loading) === 'string') {
    showLoading = true
    loadingTarget = loading
  } else if (loading === false) {
    showLoading = false
    loadingTarget = 'body'
  } else {
    showLoading = true
    loadingTarget = 'body'
  }
  return new Promise((resolve, reject) => {
    axios.post(url, data, { headers: { 'Content-Type': 'application/json', 'showLoading': showLoading, 'loadingTarget': loadingTarget } }).then(
      response => {
        resolve(response)
      },
      err => {
        reject(err)
      }
    )
  })
}


/*封装delete请求 */
export function deleteData (url, data, loading, showLoading, loadingTarget) {
  if (typeof (loading) === 'boolean') {
    showLoading = loading
    loadingTarget = 'body'
  } else if (typeof (loading) === 'string') {
    showLoading = true
    loadingTarget = loading
  } else if (loading === false) {
    showLoading = false
    loadingTarget = 'body'
  } else {
    showLoading = true
    loadingTarget = 'body'
  }
  return new Promise((resolve, reject) => {
    axios.delete(url, {
      params: data,
      headers: {'showLoading': showLoading, 'loadingTarget': loadingTarget} 
    }).then(function (response) {
        resolve(response)
      }).catch(function (err) {
        reject(err)
      });
  })
}